"""
doc
"""

import logging

import functools

from django.http import HttpRequest


from app_common import app_except

from . import models

logger = logging.getLogger("log")

UserType = models.WxUser.UserType


def check_login(user_type: dict[UserType]):
    """admin login check"""

    def _check_login(func):
        """admin login check"""

        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            def proxy_user(origin_user) -> models.WxUser:
                proxy_user_uuid = request.META.get("HTTP_X_PROXY_USER_UUID", None)
                if not proxy_user_uuid:
                    return origin_user

                proxy_user = (
                    models.WxUser.objects.filter(deleted=False)
                    .filter(uuid=proxy_user_uuid)
                    .first()
                )
                if not proxy_user:
                    raise app_except.ObjNotExist(
                        msg=f"被代理用户不存在, user uuid: {proxy_user_uuid}"
                    )
                return proxy_user

            request = kwargs.get("request", None) or args[0]
            _meta = request.META
            openid = request.META.get("HTTP_X_WX_OPENID", None)
            if openid:
                wx_user = (
                    models.WxUser.objects.filter(deleted=False)
                    .filter(openid=openid)
                    .first()
                )
                if wx_user:
                    request.origin_user = wx_user
                    request.user = wx_user
                    if wx_user.user_type == wx_user.UserType.OWNER.value:
                        request.user = proxy_user(wx_user)
                    if request.user.user_type in user_type:
                        return func(*args, **kwargs)
                raise app_except.NoAccess(msg=f"wx login. need {user_type}")

            _user: models.WxUser = request.user
            if _user:
                request.origin_user = _user
                is_passwd_login = _user.is_authenticated
                if is_passwd_login:
                    if _user.user_type == _user.UserType.OWNER.value:
                        request.user = proxy_user(_user)
                    if request.user.user_type in user_type:
                        return func(*args, **kwargs)
            raise app_except.NoAccess(msg=f"passwd login. need {user_type}")

        return wrapper

    return _check_login


anonymous_or_custom_access = [
    app_except.app_try,
    check_login(
        {
            user_tppe: True
            for user_tppe in [UserType.ANONYMOUS.value, UserType.CUSTOM.value]
        }
    ),
]

custom_access = [
    app_except.app_try,
    check_login({user_tppe: True for user_tppe in [UserType.CUSTOM.value]}),
]
owner_access = [
    app_except.app_try,
    check_login({user_tppe: True for user_tppe in [UserType.OWNER.value]}),
]
custom_or_owner_access = [
    app_except.app_try,
    check_login(
        {user_tppe: True for user_tppe in [UserType.CUSTOM.value, UserType.OWNER.value]}
    ),
]
all_user_access = [
    app_except.app_try,
    check_login({user_tppe: True for user_tppe in UserType.values}),
]
